package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import static com.leyou.common.constants.MQConstants.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private SpuDetailService spuDetailService;

    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public PageDTO<SpuDTO> querySpuByPage(Long page, Long rows, Long brandId, Long categoryId, Long id, Boolean saleable) {

        Page<Spu> iPage = this.query()
                .eq(brandId != null, "brand_id", brandId)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(id != null, "id", id)
                .eq(saleable != null, "saleable", saleable)
                .page(new Page<>(page, rows));

        long total = iPage.getTotal();
        long pages = iPage.getPages();

        List<SpuDTO> spuDTOList = SpuDTO.convertEntityList(iPage.getRecords());

        for (SpuDTO spuDTO : spuDTOList) {
            // 查询spu的分类和品牌的名称
            handleCategoryAndBrandName(spuDTO);
        }

        return new PageDTO<>(total, pages, spuDTOList);
    }

    @Override
    @Transactional
    public void updateSpuSaleable(Long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        result(this.updateById(spu), 500, "更新");
        result(this.skuService.update()
                .eq("spu_id", id)
                .set("saleable", saleable)
                .update(), 500, "更新");

        // 3.发送MQ消息
        String routingKey = saleable ? RoutingKeyConstants.ITEM_UP_KEY : RoutingKeyConstants.ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ExchangeConstants.ITEM_EXCHANGE_NAME, routingKey, id);
    }

    @Override
    @Transactional
    public void addGoods(SpuDTO spuDTO) {

        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(false);
        result(this.save(spu), 500, "新增商品");

        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
        result(spuDetailService.save(spuDetail), 500, "新增商品");

        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        List<Sku> skuList = skuDTOList.stream()
                .map(skuDTO -> {
                    Sku sku = skuDTO.toEntity(Sku.class);
                    sku.setSaleable(false);
                    sku.setSpuId(spu.getId());
                    return sku;
                }).collect(Collectors.toList());
        skuService.saveBatch(skuList);
    }

    @Override
    public void updateGoods(SpuDTO spuDTO) {
        Long spuDTOId = spuDTO.getId();
        if (spuDTOId != null) {
            result(this.updateById(spuDTO.toEntity(Spu.class)), 500, "更新商品");
        }

        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        if (spuDetailDTO.getSpuId() != null && spuDetailDTO != null) {
            result(spuDetailService.updateById(spuDetailDTO.toEntity(SpuDetail.class)), 500, "更新商品");
        }

        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        List<Sku> skuList = skuDTOList.stream()
                .map(skuDTO -> skuDTO.toEntity(Sku.class))
                .collect(Collectors.toList());
        Map<Boolean, List<Sku>> map = skuList.stream()
                .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));
        List<Sku> listToAddOrUpdate = map.get(true);
        if (CollectionUtils.isEmpty(listToAddOrUpdate)) {
            result(skuService.saveOrUpdateBatch(listToAddOrUpdate), 500, "更新商品");
        }
        List<Sku> listToDelete = map.get(false);
        if (CollectionUtils.isEmpty(listToDelete)) {
            result(skuService.removeByIds(
                    listToDelete.stream()
                            .map(sku -> sku.getId())
                            .collect(Collectors.toList())
            ), 500, "更新商品");

        }
    }


    public void result(Boolean b, Integer status, String type) {
        if (!b) {
            throw new LyException(status, type + "失败");
        }
    }

    private void handleCategoryAndBrandName(SpuDTO spuDTO) {
        // 根据品牌id查询品牌名称
        Brand brand = brandService.getById(spuDTO.getBrandId());
        if (brand != null) {
            spuDTO.setBrandName(brand.getName());
        }
        // 根据三级分类id查询分类集合
        List<Category> categoryList = categoryService.listByIds(spuDTO.getCategoryIds());
        if (!CollectionUtils.isEmpty(categoryList)) {
            // 取出分类的名称，拼接起来
            String names = categoryList.stream().map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(names);
        }

    }
}
